/************************************************************************
 *    
 *  detector construction
 *
 ************************************************************************/

#include "DetectorConstruction.hh"

using namespace std;

// constructor
DetectorConstruction::DetectorConstruction(HistoManager* HM, Data* Data)
  :histoManager(HM), data(Data), miniball(NULL) {;}

// destructor
DetectorConstruction::~DetectorConstruction() 
{
  if(miniball)
    {
      delete miniball;
      miniball=NULL;
    }
}

// construction of detectors
G4VPhysicalVolume* DetectorConstruction::Construct()
{
  G4NistManager* NistManager = G4NistManager::Instance();

  NistManager->SetVerbose(data->VerboseLevel);

  
  G4int i, SensitiveDetectorIndex = 0;
  G4String tmp;
  G4double x=0,y=0,angle=0;
  G4double x_pcb=0,y_pcb=0;
  //G4double x_pcb_b=0,y_pcb_b=0;
  G4ThreeVector position;
  G4RotationMatrix** frotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** brotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** ferotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** berotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** fpcbrotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** bpcbrotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** fepcbrotation = new G4RotationMatrix*[data->Quadrants];
  G4RotationMatrix** bepcbrotation = new G4RotationMatrix*[data->Quadrants];
  G4double density;

  MiniBallMaterial* materials = new MiniBallMaterial();

  G4Material* Aluminum = materials->GetMaterialAl();

  //  G4Material* vacuum = materials->GetMaterialVacuum();

  //definition of needed Elements
  //G4Element* H = new G4Element("Hydrogen", "H", 1, 1.00794*g/mole);
  //G4Element* B = new G4Element("Bor", "B", 5, 10.811*g/mole);
  //G4Element* C = new G4Element("Carbon", "C", 6, 12.0107*g/mole);
  //G4Element* O = new G4Element("Oxygen", "O", 8, 15.9994*g/mole);
  //G4Element* Mg = new G4Element("Magnesium", "Mg", 12, 24.3050*g/mole);
  //G4Element* Al = new G4Element("Aluminum", "Al", 13, 26.981538*g/mole);
  //G4Element* Si = new G4Element("Silicon", "Si", 14., 28.0855*g/mole);
  //G4Element* Ca = new G4Element("Calcium", "Ca", 20, 40.078*g/mole);
  //G4Element* Cu = new G4Element("Copper", "Cu", 29, 63.546*g/mole);

  G4Element* H  = NistManager->FindOrBuildElement("H" );
  G4Element* B  = NistManager->FindOrBuildElement("B" );
  G4Element* C  = NistManager->FindOrBuildElement("C" );
  G4Element* O  = NistManager->FindOrBuildElement("O" );
  G4Element* Mg = NistManager->FindOrBuildElement("Mg");
  G4Element* Al = NistManager->FindOrBuildElement("Al");
  G4Element* Si = NistManager->FindOrBuildElement("Si");
  G4Element* Ca = NistManager->FindOrBuildElement("Ca");
  G4Element* Cu = NistManager->FindOrBuildElement("Cu");

  // definition of silicon
  //G4Material* Silicon = new G4Material("silicon", 2.33*g/cm3, 1);
  //Silicon->AddElement(Si,1.);
  G4Material* Silicon = NistManager->FindOrBuildMaterial("G4_Si");

  //definition of fiber glass
  //composition of fiber glass in mass percent (from CD Roempp Chemie Lexikon-Version 1.0, Stuttgart/New York: Georg Thieme Verlag 1995):
  //SiO2  	B2O3  	CaO  	Al2O3  	else
  //54  	10  	17,5  	14  	4,5 MgO

  //SiO2
  G4Material* SiO2 = NistManager->FindOrBuildMaterial("G4_SILICON_DIOXIDE");

  if(SiO2 == NULL)
    {
      cerr<<"Warning, failed to get SiO2 (G4_SILICON_DIOXIDE) from NistManager"<<endl;

      density = 2.2*g/cm3;
      SiO2 = new G4Material("SiO2", density, 2);

      SiO2->AddElement(Si, 1);
      SiO2->AddElement(O, 2);
    }

  //B2O3

  G4Material* B2O3 = NistManager->FindOrBuildMaterial("G4_BORON_OXIDE");

  if(B2O3 == NULL)
    {
      cerr<<"Warning, failed to get B2O3 (G4_BORON_OXIDE) from NistManager"<<endl;

      density = 1.8*g/cm3;
      B2O3 = new G4Material("B2O3", density, 2);
      
      B2O3->AddElement(B, 2);
      B2O3->AddElement(O, 3);
    }

  //CaO

  G4Material* CaO = NistManager->FindOrBuildMaterial("G4_CALCIUM_OXIDE");

  if(CaO == NULL)
    {
      cerr<<"Warning, failed to get CaO (G4_CALCIUM_OXIDE) from NistManager"<<endl;

      density = 3.37*g/cm3;
      CaO = new G4Material("CaO", density, 2);
      
      CaO->AddElement(Ca, 1);
      CaO->AddElement(O, 1);
    }

  //Al2O3

  G4Material* Al2O3 = NistManager->FindOrBuildMaterial("G4_ALUMINUM_OXIDE");

  if(Al2O3 == NULL)
    {
      cerr<<"Warning, failed to get Al2O3 (G4_ALUMINUM_OXIDE) from NistManager"<<endl;
      
      density = 3.98*g/cm3;
      Al2O3 = new G4Material("Al2O3", density, 2);
      
      Al2O3->AddElement(Al, 2);
      Al2O3->AddElement(O, 3);
    }

  //MgO

  G4Material* MgO = NistManager->FindOrBuildMaterial("G4_MAGNESIUM_OXIDE");

  if(MgO == NULL)
    {
      cerr<<"Warning, failed to get MgO (G4_MAGNESIUM_OXIDE) from NistManager"<<endl;

      density = 3.65*g/cm3;
      MgO = new G4Material("MgO", density, 2);
      
      MgO->AddElement(Mg, 1);
      MgO->AddElement(O, 1);
    }

  //fiber glass
  density = 2.5*g/cm3; //2.0 - 2.62
  G4Material* FiberGlass = new G4Material("FiberGlass", density, 5);

  FiberGlass->AddMaterial(SiO2,  0.54);
  FiberGlass->AddMaterial(B2O3,  0.10);
  FiberGlass->AddMaterial(CaO,   0.175);
  FiberGlass->AddMaterial(Al2O3, 0.14);
  FiberGlass->AddMaterial(MgO,   0.045);

  //definition of Epoxy
  density = 1.2*g/cm3;
  G4Material* Epoxy = new G4Material("Epoxy", density, 3);

  Epoxy->AddElement(H, 24);
  Epoxy->AddElement(C, 21);
  Epoxy->AddElement(O, 4);

  //definition of PCB
  density = 1.8*g/cm3; //1.8 - 2.0
  G4Material* PCB = new G4Material("PCB", density, 3);

  PCB->AddMaterial(FiberGlass, 0.70);
  PCB->AddMaterial(Epoxy, 0.25);
  PCB->AddElement(Cu, 0.05);

  //definition of Mylar
  //density     = 1.397 *g/cm3;
  //G4Material* Mylar = new G4Material("Mylar",density , 3);
  //
  //Mylar -> AddElement(H, 8);
  //Mylar -> AddElement(C,10);
  //Mylar -> AddElement(O, 4);

  G4Material* Mylar = NistManager->FindOrBuildMaterial("G4_MYLAR");

  // create world volume
  MiniBallWorld* world = new MiniBallWorld(materials);
  mother=world->Construct();

  // initialize detector
  miniball
    = new MiniBallDetectorArray(histoManager, mother, data->settings->MiniballNb, data->settings->MiniballName,
				data->settings->MiniballType, data->settings->MiniballRho, data->settings->MiniballTheta, data->settings->MiniballPhi, data->settings->MiniballSpin,
				MINIBALL_CAPSULE, MINIBALL_CRYOWALL,
				materials);
  
  miniball->SetAllDeadlayer(0.7*micrometer, DEADLAYER_OUTER_CONTACT);

  for(i = 0; i < 8; i++)
    {
      if(data->settings->MiniballRelativeEfficiency[i][0] > 0.)
	{
	  miniball->SetRelativeEfficiencyDetA(i, data->settings->MiniballRelativeEfficiency[i][0]);
	}
      if(data->settings->MiniballRelativeEfficiency[i][1] > 0.)
	{
	  miniball->SetRelativeEfficiencyDetB(i, data->settings->MiniballRelativeEfficiency[i][1]);
	}
      if(data->settings->MiniballRelativeEfficiency[i][2] > 0.)
	{
	  miniball->SetRelativeEfficiencyDetC(i, data->settings->MiniballRelativeEfficiency[i][2]);
	}
    }
  
  miniball->Construct();

#ifdef G4VIS_USE
  //CD
  G4VisAttributes* fCDVisAtt = new G4VisAttributes(true,G4Colour(1.0,1.0,0.0));
  G4VisAttributes* bCDVisAtt = new G4VisAttributes(true,G4Colour(1.0,1.0,0.0));
  G4VisAttributes* fCDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.5,0.0));
  //G4VisAttributes* bCDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.5,0.0));
  G4VisAttributes* bCDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.0,0.0));

  G4VisAttributes* hfCDVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.8,0.0));
  G4VisAttributes* hbCDVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.8,0.0));
  G4VisAttributes* hfCDEVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.5,0.0));
  G4VisAttributes* hbCDEVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.5,0.0));

  G4VisAttributes* fCDPCBVisAtt = new G4VisAttributes(true,G4Colour(0.0,0.5,0.0));
  //G4VisAttributes* bCDPCBVisAtt = new G4VisAttributes(true,G4Colour(0.5,0.0,0.0));
  G4VisAttributes* bCDPCBVisAtt = new G4VisAttributes(true,G4Colour(0.0,0.5,0.0));
  G4VisAttributes* fCDEPCBVisAtt = new G4VisAttributes(true,G4Colour(0.0,0.5,0.0));
  //G4VisAttributes* bCDEPCBVisAtt = new G4VisAttributes(true,G4Colour(0.5,0.0,0.0));
  G4VisAttributes* bCDEPCBVisAtt = new G4VisAttributes(true,G4Colour(0.0,0.5,0.0));

  G4VisAttributes* hfCDPCBVisAtt = new G4VisAttributes(false,G4Colour(0.0,0.5,0.0));
  G4VisAttributes* hbCDPCBVisAtt = new G4VisAttributes(false,G4Colour(0.5,0.0,0.0));
  G4VisAttributes* hfCDEPCBVisAtt = new G4VisAttributes(false,G4Colour(0.0,0.5,0.0));
  G4VisAttributes* hbCDEPCBVisAtt = new G4VisAttributes(false,G4Colour(0.5,0.0,0.0));


  //BD
  G4VisAttributes* fBDVisAtt = new G4VisAttributes(true,G4Colour(1.0,1.0,0.0));
  G4VisAttributes* bBDVisAtt = new G4VisAttributes(true,G4Colour(1.0,1.0,0.0));
  G4VisAttributes* fBDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.5,0.0));
  //G4VisAttributes* bBDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.5,0.0));
  G4VisAttributes* bBDEVisAtt = new G4VisAttributes(true,G4Colour(1.0,0.0,0.0));

  G4VisAttributes* hfBDVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.8,0.0));
  G4VisAttributes* hbBDVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.8,0.0));
  G4VisAttributes* hfBDEVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.5,0.0));
  G4VisAttributes* hbBDEVisAtt = new G4VisAttributes(false,G4Colour(0.8,0.5,0.0));

  //barrel pcb
  //G4VisAttributes* fBDPCBVisAtt = new G4VisAttributes(true, G4Colour(0.0,0.5,0.0));
  G4VisAttributes* fBDPCBVisAtt = new G4VisAttributes(true, G4Colour(0.0,0.5,0.0));
  G4VisAttributes* bBDPCBVisAtt = new G4VisAttributes(true, G4Colour(0.0,0.5,0.0));
  G4VisAttributes* hfBDPCBVisAtt = new G4VisAttributes(false, G4Colour(0.0,0.4,0.0));
  G4VisAttributes* hbBDPCBVisAtt = new G4VisAttributes(false, G4Colour(0.0,0.4,0.0));

  //test colors
  //G4VisAttributes* red = new G4VisAttributes(true,G4Colour(1.0,0.0,0.0));
  //G4VisAttributes* green = new G4VisAttributes(true,G4Colour(0.0,1.0,0.0));
  //G4VisAttributes* blue = new G4VisAttributes(true,G4Colour(0.0,0.0,1.0));


  /*
  G4VisAttributes* fPCBVisAtt = NULL;
  if(data->Cut&(1<<9))
    fPCBVisAtt = new G4VisAttributes(false, G4Colour(0.0,0.5,0.0));
  else
    fPCBVisAtt = new G4VisAttributes(true, G4Colour(0.0,0.5,0.0));
  G4VisAttributes* bPCBVisAtt = NULL;
  if(data->Cut&(1<<1))
    bPCBVisAtt = new G4VisAttributes(false, G4Colour(0.0,0.5,0.0));
  else
    bPCBVisAtt = new G4VisAttributes(true, G4Colour(0.0,0.5,0.0));
  */
  //foils
  G4VisAttributes* FCDFoilVisAtt= new G4VisAttributes(true,G4Colour(0.0,1.0,1.0));
  G4VisAttributes* BCDFoilVisAtt= new G4VisAttributes(true,G4Colour(0.0,1.0,1.0));
  G4VisAttributes* fBDFoilVisAtt= new G4VisAttributes(false,G4Colour(0.0,1.0,1.0));
  G4VisAttributes* bBDFoilVisAtt= new G4VisAttributes(true,G4Colour(0.0,1.0,1.0));

  //G4VisAttributes* BVertFoilVisAtt= new G4VisAttributes(true,G4Colour(0.8,0.1,0.1));
  G4VisAttributes* BVertFoilVisAtt= new G4VisAttributes(true,G4Colour(0.0,1.0,1.0));
  //target
  G4VisAttributes* TargetMaterialVisAtt = new G4VisAttributes(true,G4Colour(0.0,0.0,1.0));
  //chamber
  G4VisAttributes* ChamberVisAtt= new G4VisAttributes(true,G4Colour(0.7,0.7,0.7));
  
#endif

  //sensitive detector manager
  G4SDManager* SDman = G4SDManager::GetSDMpointer();

  //CD detectors 
  G4Tubs*** CDQuadrant_solid;
  G4Tubs*** PCBQuadrant_tmp;
  G4SubtractionSolid** PCBQuadrant_solid;

  int et = data->ExperimentType;
  int nofCDs=0;
  if(et != 2){
    nofCDs = 1;
    if(et == 4)
      nofCDs = 2;
    if(data->CDPad==1)
      nofCDs*=2;
    CDQuadrant_solid = new G4Tubs**[nofCDs];
    PCBQuadrant_tmp = new G4Tubs**[nofCDs];
    PCBQuadrant_solid = new G4SubtractionSolid*[nofCDs];

    for(i=0;i<nofCDs;i++){
      CDQuadrant_solid[i] = new G4Tubs*[4];
      PCBQuadrant_tmp[i] = new G4Tubs*[4];
    }
    if(data->VerboseLevel > 1)
      cout << "creating " << nofCDs << " CDs" << endl;

    //PCB solids
    G4Tubs* pcbtot_solid[2];
    G4Box* pcbhole[2];
    if(data->Cut&(1<<4)){
      pcbtot_solid[0] = new G4Tubs("PCB1_solid", 0., data->settings->SSDPCBOuterRad, data->settings->SSDPCBStripThickness/2.,45.*degree, 270.*degree);
      pcbtot_solid[1] = new G4Tubs("PCB1_solid", 0., data->settings->SSDPCBOuterRad, data->settings->SSDPCBPadThickness/2.,45.*degree, 270.*degree);
    }
    else{
      pcbtot_solid[0] = new G4Tubs("PCB1_solid", 0., data->settings->SSDPCBOuterRad, data->settings->SSDPCBStripThickness/2.,0.*degree, 360.*degree);
      pcbtot_solid[1] = new G4Tubs("PCB1_solid", 0., data->settings->SSDPCBOuterRad, data->settings->SSDPCBPadThickness/2.,0.*degree, 360.*degree);
    }
    
    pcbhole[0] = new G4Box("PCBHole_solid",data->settings->SSDPCBInnerRad/sqrt(2.),data->settings->SSDPCBInnerRad/sqrt(2.),data->settings->SSDPCBStripThickness+1.e-2);
    pcbhole[1] = new G4Box("PCBHole_solid",data->settings->SSDPCBInnerRad/sqrt(2.),data->settings->SSDPCBInnerRad/sqrt(2.),data->settings->SSDPCBPadThickness+1.e-2);
    
    PCBQuadrant_solid[0] = new G4SubtractionSolid("tmpPCB_solid",pcbtot_solid[0],pcbhole[0]);
    if(et==4)
      PCBQuadrant_solid[2] = new G4SubtractionSolid("tmpPCB_solid",pcbtot_solid[0],pcbhole[0]);
    if(data->CDPad==1){
      PCBQuadrant_solid[1] = new G4SubtractionSolid("tmpPCB_solid",pcbtot_solid[1],pcbhole[1]);
      if(et==4)
	PCBQuadrant_solid[3] = new G4SubtractionSolid("tmpPCB_solid",pcbtot_solid[1],pcbhole[1]);
    }


    //ssdpcb_solid[0] = new G4SubtractionSolid("SSDPCB_solid",tmppcb_solid[0],si_solid[3]);
    //ssdpcb_solid[1] = new G4SubtractionSolid("SSDPCB_solid",tmppcb_solid[1],si_solid[4]);

      
    for(i=0;i<4;i++){ // 4 quadrants
      if(et==0 || et==4){//ForwardCD
	if(data->VerboseLevel > 1)
	  cout << "creating forward CD" << endl;
	CDQuadrant_solid[0][i] = new G4Tubs(Form("FCDQuadrant%d_solid",i), data->settings->SSDInnerRad, data->settings->SSDOuterRad, data->settings->fSSDThickness[i]/2.-data->settings->SSDDeadLayer/2.,data->settings->SSDRotation+(i+1)*90.*degree-data->settings->SSDSegAngle/2., data->settings->SSDAngle);
	PCBQuadrant_tmp[0][i] = new G4Tubs(Form("FPCBQuadrant%d_tmp",i), data->settings->SSDInnerRad, data->settings->SSDOuterRad, data->settings->SSDPCBStripThickness+1.e-1,data->settings->SSDRotation+(i+1)*90.*degree-data->settings->SSDSegAngle/2., data->settings->SSDAngle);
	PCBQuadrant_solid[0] = new G4SubtractionSolid("tmpPCB_solid",PCBQuadrant_solid[0],PCBQuadrant_tmp[0][i]);

	if(data->CDPad==1){
	  if(data->VerboseLevel > 1)
	    cout << "creating forward CDE" << endl;
	  CDQuadrant_solid[1][i] = new G4Tubs(Form("FCDEQuadrant%d_solid",i), data->settings->SSDInnerRad, data->settings->SSDPadOuterRad, data->settings->feSSDThickness[i]/2.-data->settings->SSDDeadLayer/2.,data->settings->SSDRotation+(i+1)*90.*degree-data->settings->SSDSegAngle/2., data->settings->SSDAngle);
	  PCBQuadrant_tmp[1][i] = new G4Tubs(Form("FEPCBQuadrant%d_tmp",i), data->settings->SSDInnerRad, data->settings->SSDPadOuterRad, data->settings->SSDPCBPadThickness+1.e-1,data->settings->SSDRotation+(i+1)*90.*degree-data->settings->SSDSegAngle/2., data->settings->SSDAngle);
	  PCBQuadrant_solid[1] = new G4SubtractionSolid("tmpPCB_solid",PCBQuadrant_solid[1],PCBQuadrant_tmp[1][i]);
	}
      }
      if(et==1 || et==3 || et==4){
	if(data->VerboseLevel > 1)
	  cout << "creating backward CD" << endl;
	  cout << "i "<< i << " et/4+(et/4)*data->CDPad " << et/4+(et/4)*data->CDPad << endl;
	  CDQuadrant_solid[et/4+(et/4)*data->CDPad][i] = new G4Tubs(Form("BCDQuadrant%d_solid",i), data->settings->SSDInnerRad, data->settings->SSDOuterRad, data->settings->bSSDThickness[i]/2.-data->settings->SSDDeadLayer/2.,data->settings->SSDRotation+i*90.*degree, data->settings->SSDAngle);
	PCBQuadrant_tmp[et/4+(et/4)*data->CDPad][i] = new G4Tubs(Form("BPCBQuadrant%d_tmp",i), data->settings->SSDInnerRad, data->settings->SSDOuterRad, data->settings->SSDPCBStripThickness+1.e-1,data->settings->SSDRotation+i*90.*degree, data->settings->SSDAngle);
	PCBQuadrant_solid[et/4+(et/4)*data->CDPad] = new G4SubtractionSolid("tmpPCB_solid",PCBQuadrant_solid[et/4+(et/4)*data->CDPad],PCBQuadrant_tmp[et/4+(et/4)*data->CDPad][i]);
	if(data->CDPad==1){
	  if(data->VerboseLevel > 1)
	    cout << "creating backward CDE" << endl;
	  cout << "i "<< i << " 1+et/4+(et/4)*data->CDPad " << 1+et/4+(et/4)*data->CDPad << endl;
	  CDQuadrant_solid[1+et/4+(et/4)*data->CDPad][i] = new G4Tubs(Form("BCDEQuadrant%d_solid",i), data->settings->SSDInnerRad, data->settings->SSDPadOuterRad, data->settings->beSSDThickness[i]/2.-data->settings->SSDDeadLayer/2.,data->settings->SSDRotation+i*90.*degree, data->settings->SSDAngle);
	  cout << "created CD solid " << endl;
	  PCBQuadrant_tmp[1+et/4+(et/4)*data->CDPad][i] = new G4Tubs(Form("BEPCBQuadrant%d_tmp",i), data->settings->SSDInnerRad, data->settings->SSDPadOuterRad, data->settings->SSDPCBPadThickness+1.e-1,data->settings->SSDRotation+i*90.*degree, data->settings->SSDAngle);
	  cout << "created PCB tmp " << endl;
	  PCBQuadrant_solid[1+et/4+(et/4)*data->CDPad] = new G4SubtractionSolid("tmpPCB_solid",PCBQuadrant_solid[1+et/4+(et/4)*data->CDPad],PCBQuadrant_tmp[1+et/4+(et/4)*data->CDPad][i]);
	  cout << "created PCB solid " << endl;
	}
      }
    }
    if(data->VerboseLevel > 1)
      cout << "done with creating CDs" << endl;
    
    //logical volumes and placements
    G4LogicalVolume* ForwardCD_log[4];
    G4LogicalVolume* ForwardCDE_log[4];
    G4LogicalVolume* BackwardCD_log[4];
    G4LogicalVolume* BackwardCDE_log[4];

    G4LogicalVolume* PCBCD_log[4];
    
    // register sensitive detector
    
    SensitiveDetector* ForwardCD_sensitive_detector[4];
    SensitiveDetector* ForwardCDE_sensitive_detector[4];
    SensitiveDetector* BackwardCD_sensitive_detector[4];
    SensitiveDetector* BackwardCDE_sensitive_detector[4];
    
    // -------------------- forward CD --------------------
    if(et==0 || et==4){
      for(i=0;i<4;i++){ // 4 quadrants
	if(data->VerboseLevel > 1)
	  cout << "creating logical volume for forward CDs" << endl;

	ForwardCD_log[i] = new G4LogicalVolume(CDQuadrant_solid[0][i], Silicon, Form("ForwardCD%d_log",i));
	position.set(0, 0, data->settings->SSDZPosition - data->settings->fSSDThickness[i]/2.);      
	new G4PVPlacement(0, position, Form("ForwardCD%d",i), ForwardCD_log[i], mother, false, 0);

	ForwardCD_sensitive_detector[i] = new SensitiveDetector(Form("ForwardCD%d",i), SensitiveDetectorIndex, data);
	SDman->AddNewDetector(ForwardCD_sensitive_detector[i]);
	ForwardCD_log[i]->SetSensitiveDetector(ForwardCD_sensitive_detector[i]);
	SensitiveDetectorIndex++;
	  
#ifdef G4VIS_USE
	if((data->Cut&(1<<3)) && i == 1)
	  ForwardCD_log[i]->SetVisAttributes(*hfCDVisAtt);
	else	    
	  ForwardCD_log[i]->SetVisAttributes(*fCDVisAtt);
#endif

	if(data->CDPad==1){
	  ForwardCDE_log[i] = new G4LogicalVolume(CDQuadrant_solid[1][i], Silicon, Form("ForwardCD%d_log",i));
	  position.set(0, 0, data->settings->CDEZPosition - data->settings->feSSDThickness[i]/2.);      
	  new G4PVPlacement(0, position, Form("ForwardCDE%d",i), ForwardCDE_log[i], mother, false, 0);

	  ForwardCDE_sensitive_detector[i] = new SensitiveDetector(Form("ForwardCDE%d",i), SensitiveDetectorIndex, data);
	  SDman->AddNewDetector(ForwardCDE_sensitive_detector[i]);
	  ForwardCDE_log[i]->SetSensitiveDetector(ForwardCDE_sensitive_detector[i]);
	  SensitiveDetectorIndex++;
	  
#ifdef G4VIS_USE
	  if((data->Cut&(1<<3)) && i == 1)
	    ForwardCDE_log[i]->SetVisAttributes(*hfCDEVisAtt);
	  else	    
	    ForwardCDE_log[i]->SetVisAttributes(*fCDEVisAtt);
#endif
	}
      }
    }
    // -------------------- backward CD --------------------
    if(et==1 || et==3 || et==4){
      for(i=0;i<4;i++){ // 4 quadrants
	if(data->VerboseLevel > 1)
	  cout << "creating logical volume for backward CDs" << endl;
	BackwardCD_log[i] = new G4LogicalVolume(CDQuadrant_solid[et/4+(et/4)*data->CDPad][i], Silicon, Form("BackwardCD%d_log",i));
	position.set(0, 0, -(data->settings->SSDZPosition - data->settings->bSSDThickness[i]/2.));      
	new G4PVPlacement(0, position, Form("BackwardCD%d",i), BackwardCD_log[i], mother, false, 0);

	BackwardCD_sensitive_detector[i] = new SensitiveDetector(Form("BackwardCD%d",i), SensitiveDetectorIndex, data);
	SDman->AddNewDetector(BackwardCD_sensitive_detector[i]);
	BackwardCD_log[i]->SetSensitiveDetector(BackwardCD_sensitive_detector[i]);
	SensitiveDetectorIndex++;
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<3)) && i == 1)
	    BackwardCD_log[i]->SetVisAttributes(*hbCDVisAtt);
	  else
	    BackwardCD_log[i]->SetVisAttributes(*bCDVisAtt);
	}
	else
	  BackwardCD_log[i]->SetVisAttributes(*hbCDVisAtt);
#endif

	if(data->CDPad==1){
	  if(data->VerboseLevel > 1)
	    cout << "creating logical volume for backward CDEs" << endl;
	  BackwardCDE_log[i] = new G4LogicalVolume(CDQuadrant_solid[1+et/4+(et/4)*data->CDPad][i], Silicon, Form("BackwardCD%d_log",i));
	  position.set(0, 0, -(data->settings->CDEZPosition - data->settings->beSSDThickness[i]/2.));      
	  new G4PVPlacement(0, position, Form("BackwardCDE%d",i), BackwardCDE_log[i], mother, false, 0);

	  BackwardCDE_sensitive_detector[i] = new SensitiveDetector(Form("BackwardCDE%d",i), SensitiveDetectorIndex, data);
	  SDman->AddNewDetector(BackwardCDE_sensitive_detector[i]);
	  BackwardCDE_log[i]->SetSensitiveDetector(BackwardCDE_sensitive_detector[i]);
	  SensitiveDetectorIndex++;

	  
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<3)) && i == 1)
	    BackwardCDE_log[i]->SetVisAttributes(*hbCDEVisAtt);
	  else	    
	    BackwardCDE_log[i]->SetVisAttributes(*bCDEVisAtt);
	}
	else
	  BackwardCDE_log[i]->SetVisAttributes(*hbCDEVisAtt);
#endif
	}
      }
    }
    if(et==0 || et==4){
      if(data->VerboseLevel > 1)
	cout << "forward pcb" << endl;
      PCBCD_log[0] = new G4LogicalVolume(PCBQuadrant_solid[0], PCB, "PCBForwardCD0_log");
      position.set(0, 0, data->settings->SSDZPosition - data->settings->SSDPCBStripThickness/2.);      
      new G4PVPlacement(0, position, "PCBForwardCD0", PCBCD_log[0], mother, false, 0);	
#ifdef G4VIS_USE
      PCBCD_log[0]->SetVisAttributes(*fCDPCBVisAtt);
#endif
      if(data->CDPad==1){
	if(data->VerboseLevel > 1)
	  cout << "forward pad pcb" << endl;
	PCBCD_log[1] = new G4LogicalVolume(PCBQuadrant_solid[1], PCB, "PCBForwardCD1_log");
	position.set(0, 0, data->settings->CDEZPosition - data->settings->SSDPCBPadThickness/2.);      
	new G4PVPlacement(0, position, "PCBForwardCD1", PCBCD_log[1], mother, false, 0);	
#ifdef G4VIS_USE
	PCBCD_log[1]->SetVisAttributes(*fCDEPCBVisAtt);
#endif
      }
    }
    if(et==1 || et==3 || et==4){
      if(data->VerboseLevel > 1)
	cout << "backward pcb" << endl;
      PCBCD_log[et/4+(et/4)*data->CDPad] = new G4LogicalVolume(PCBQuadrant_solid[et/4+(et/4)*data->CDPad], PCB, "PCBForwardCD2_log");
      position.set(0, 0, -(data->settings->SSDZPosition - data->settings->SSDPCBStripThickness/2.));      
      new G4PVPlacement(0, position, "PCBForwardCD%2", PCBCD_log[et/4+(et/4)*data->CDPad], mother, false, 0);	
#ifdef G4VIS_USE
      if(!data->Coulex)
	PCBCD_log[et/4+(et/4)*data->CDPad]->SetVisAttributes(*bCDPCBVisAtt);
      else	    
	PCBCD_log[et/4+(et/4)*data->CDPad]->SetVisAttributes(*hbCDPCBVisAtt);
#endif
      if(data->CDPad==1){
	if(data->VerboseLevel > 1)
	  cout << "back pad pcb" << endl;
	PCBCD_log[et/4+(et/4)*data->CDPad+1] = new G4LogicalVolume(PCBQuadrant_solid[et/4+(et/4)*data->CDPad+1], PCB, "PCBForwardCD1_log");
	position.set(0, 0, -(data->settings->CDEZPosition - data->settings->SSDPCBPadThickness/2.));      
	new G4PVPlacement(0, position, "PCBForwardCD1", PCBCD_log[et/4+(et/4)*data->CDPad+1], mother, false, 0);	
#ifdef G4VIS_USE
	PCBCD_log[et/4+(et/4)*data->CDPad+1]->SetVisAttributes(*bCDEPCBVisAtt);
#endif
      }
    }
  }//et!=2
    // barrel start
  if(et > 1){
    //barrel
    G4Box* fbarrel_solid[4];
    G4Box* bbarrel_solid[4];
    G4Box* febarrel_solid[4];
    G4Box* bebarrel_solid[4];
    
    if(data->VerboseLevel > 1)
      cout<<"BarrelType = "<<data->BarrelType<<", barrel dimensions: "<<data->settings->BarrelWidth/2.<<" x "<<data->settings->BarrelLength/2.<<endl;
    for(i=0;i<4;i++){
      fbarrel_solid[i] = new G4Box("fbarrel_solid", data->settings->BarrelWidth/2., data->settings->fBarrelThickness[i]/2., data->settings->BarrelLength/2.);
      bbarrel_solid[i] = new G4Box("bbarrel_solid", data->settings->BarrelWidth/2., data->settings->bBarrelThickness[i]/2., data->settings->BarrelLength/2.);
      febarrel_solid[i] = new G4Box("febarrel_solid", data->settings->BarrelWidth/2., data->settings->feBarrelThickness[i]/2., data->settings->BarrelLength/2.);
      if(data->BarrelType==1)
	bebarrel_solid[i] = new G4Box("bebarrel_solid", data->settings->BarrelWidth/2., data->settings->beBarrelThickness[i]/2., data->settings->BarrelLength/2.);
    }

    G4LogicalVolume** fbarrel_log;
    G4LogicalVolume** bbarrel_log;
    G4LogicalVolume** febarrel_log;
    G4LogicalVolume** bebarrel_log;

    fbarrel_log = new G4LogicalVolume*[data->Quadrants];
    bbarrel_log = new G4LogicalVolume*[data->Quadrants];
    febarrel_log = new G4LogicalVolume*[data->Quadrants];
    bebarrel_log = new G4LogicalVolume*[data->Quadrants];
    
    SensitiveDetector** FBarrel_sensitive_detector = new SensitiveDetector*[data->Quadrants];
    SensitiveDetector** BBarrel_sensitive_detector = new SensitiveDetector*[data->Quadrants];
    SensitiveDetector** FEBarrel_sensitive_detector = new SensitiveDetector*[data->Quadrants];
    SensitiveDetector** BEBarrel_sensitive_detector = new SensitiveDetector*[data->Quadrants];


    G4SubtractionSolid* deltaPCB_solid = NULL;
    G4SubtractionSolid* EPCB_solid = NULL;
    G4Box* PCB_dE = new G4Box("PCB_dE",data->settings->PCBWidth/2.,data->settings->PCBThickness/2.,data->settings->PCBLength/2.);
    //G4Box* PCB_E = new G4Box("PCB_E",data->settings->ePCBWidth/2.,data->settings->PCBThickness/2.,data->settings->PCBLength/2.);
    G4Box* PCB_hole = new G4Box("PCB_hole",data->settings->BarrelActWidth/2.,data->settings->PCBThickness/1.9,data->settings->BarrelActLength/2.);
    G4Box* PCB_corner = new G4Box("PCB_corner",data->settings->PCBRecessWidth/2.+0.1, data->settings->PCBThickness/1.9, data->settings->PCBRecessLength/2.+0.1);
    G4Box* PCB_edge = new G4Box("PCB_edge", (data->settings->PCBWidth-data->settings->ePCBWidth)/2.+0.1, data->settings->PCBThickness/1.9, (data->settings->PCBLength)/2.+0.1);

    deltaPCB_solid = new G4SubtractionSolid("deltaPCB_solid", PCB_dE, PCB_hole, new G4RotationMatrix(), G4ThreeVector(data->settings->BarrelDisplacement,0,0));

    deltaPCB_solid = new G4SubtractionSolid("deltaPCB_solid", deltaPCB_solid, PCB_corner, new G4RotationMatrix(), G4ThreeVector( -(data->settings->PCBWidth/2.-data->settings->PCBRecessWidth/2.),0,(data->settings->PCBLength/2.-data->settings->PCBRecessLength/2.) ));
    
    EPCB_solid = new G4SubtractionSolid("EPCB_solid", deltaPCB_solid, PCB_edge, new G4RotationMatrix(), G4ThreeVector(-(data->settings->PCBWidth-(data->settings->PCBWidth-data->settings->ePCBWidth)/2.)/2.,0,0));

    //EPCB_solid = new G4SubtractionSolid("EPCB_solid", EPCB_solid, PCB_corner, new G4RotationMatrix(), G4ThreeVector( -(data->settings->PCBWidth/2.-data->settings->PCBRecessWidth/2.)-(data->settings->PCBWidth-data->settings->ePCBWidth)/2.,0,(data->settings->PCBLength/2.-data->settings->PCBRecessLength/2.) ));
    
    G4LogicalVolume** fPCB_log;
    G4LogicalVolume** bPCB_log;
    G4LogicalVolume** fePCB_log;
    G4LogicalVolume** bePCB_log;
    
    fPCB_log = new G4LogicalVolume*[data->Quadrants];
    bPCB_log = new G4LogicalVolume*[data->Quadrants];
    fePCB_log = new G4LogicalVolume*[data->Quadrants];
    bePCB_log = new G4LogicalVolume*[data->Quadrants];
    
    
    for(i=0;i<data->Quadrants;i++){
      //detectors are numbered: bottom, left, top, right; first forward angles than backward angles than forward E
      //angle = i*90.*degree;
      //detectors are numbered: top, left, bottom, right; first forward angles than backward angles than forward E
      angle = i*90.*degree;
      if(data->settings->BarrelDistance == 0)
	data->settings->BarrelDistance = data->settings->BarrelActWidth/2./tan(data->settings->SSDSegAngle/2.);
      x = -sin(angle);
      y = cos(angle); //was -cos
      x_pcb = x*data->settings->BarrelDistance + cos(angle)*data->settings->BarrelDisplacement;
      y_pcb = y*data->settings->BarrelDistance - sin(angle)*data->settings->BarrelDisplacement;
      //x_pcb_b = x*data->settings->BarrelDistance + cos(angle)*data->settings->BarrelDisplacement;
      //y_pcb_b = y*data->settings->BarrelDistance - sin(angle)*data->settings->BarrelDisplacement;
      
      //forward barrel deltaE detectors
      tmp = "fbarrel_log_" + G4UIcommand::ConvertToString(i);
      fbarrel_log[i] = new G4LogicalVolume(fbarrel_solid[i], Silicon, tmp);
      
      tmp = "fbarrel_" + G4UIcommand::ConvertToString(i);
      
      position.set(x*(data->settings->BarrelDistance-data->settings->fBarrelThickness[i]/2.),y*(data->settings->BarrelDistance-data->settings->fBarrelThickness[i]/2.),data->settings->ForwardBarrelZ);
      frotation[i] = new G4RotationMatrix();
      if ((i==1)||(i==3)) frotation[i]->rotateZ(angle);
      if ((i==0)||(i==2)) frotation[i]->rotateZ(angle+180*deg);
      
      if(data->VerboseLevel > 1)	  
	cout<<"placement of volume "<<tmp<<", pos = ("<<position.x()<<", "<<position.y()<<", "<<position.z()<<"), rot = ("<<position.phi()<<", "<<position.theta()<<")"<<endl;
      
      new G4PVPlacement(frotation[i], position, tmp, fbarrel_log[i], mother, false, 0);
      // register sensitive detector
      tmp = "FBarrel_" + G4UIcommand::ConvertToString(i);
      FBarrel_sensitive_detector[i] = new SensitiveDetector(tmp, SensitiveDetectorIndex, data);
      
      SDman->AddNewDetector(FBarrel_sensitive_detector[i]);
      fbarrel_log[i]->SetSensitiveDetector(FBarrel_sensitive_detector[i]);
#ifdef G4VIS_USE
      if((data->Cut&(1<<2)) && i == 1) //was i==3
	fbarrel_log[i]->SetVisAttributes(hfBDVisAtt);
      else
	fbarrel_log[i]->SetVisAttributes(fBDVisAtt);
#endif
      SensitiveDetectorIndex++;
      
      if(data->VerboseLevel > 1)
	cout<<"DetectorConstruction: created fBarrel "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
      
      //forward barrel E detectors
      tmp = "febarrel_log_" + G4UIcommand::ConvertToString(i);
      febarrel_log[i] = new G4LogicalVolume(febarrel_solid[i], Silicon, tmp);
      
      tmp = "febarrel_" + G4UIcommand::ConvertToString(i);
      position.set(x*(data->settings->BarrelDistance+data->settings->PCBThickness+data->settings->BarrelDeltaEGap-data->settings->feBarrelThickness[i]/2.),y*(data->settings->BarrelDistance+data->settings->PCBThickness+data->settings->BarrelDeltaEGap-data->settings->feBarrelThickness[i]/2.),data->settings->ForwardBarrelZ);
      ferotation[i] = new G4RotationMatrix();
      ferotation[i]->rotateZ(angle);
      
      new G4PVPlacement(ferotation[i], position, tmp, febarrel_log[i], mother, false, 0);
      
      // register sensitive detector
      tmp = "FEBarrel_" + G4UIcommand::ConvertToString(i);
      FEBarrel_sensitive_detector[i] = new SensitiveDetector(tmp, SensitiveDetectorIndex, data);
      SDman->AddNewDetector(FEBarrel_sensitive_detector[i]);
      febarrel_log[i]->SetSensitiveDetector(FEBarrel_sensitive_detector[i]);
#ifdef G4VIS_USE
      if(!data->Coulex){
	if((data->Cut&(1<<2)) && i == 1)
	  febarrel_log[i]->SetVisAttributes(hfBDEVisAtt);
	else
	  febarrel_log[i]->SetVisAttributes(fBDEVisAtt);
      }
      else
	febarrel_log[i]->SetVisAttributes(hfBDEVisAtt);
	
#endif
      SensitiveDetectorIndex++;
      
      if(data->VerboseLevel > 1)
	cout<<"DetectorConstruction: created feBarrel "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;

      //backward barrel detectors
      tmp = "bbarrel_log_" + G4UIcommand::ConvertToString(i);
      bbarrel_log[i] = new G4LogicalVolume(bbarrel_solid[i], Silicon, tmp);
      
      tmp = "bbarrel_" + G4UIcommand::ConvertToString(i);
      position.set(x*(data->settings->BarrelDistance-data->settings->bBarrelThickness[i]/2.),y*(data->settings->BarrelDistance-data->settings->bBarrelThickness[i]/2.),data->settings->BackwardBarrelZ);
      brotation[i] = new G4RotationMatrix();
      brotation[i]->rotateZ(angle);
      
      new G4PVPlacement(brotation[i], position, tmp, bbarrel_log[i], mother, false, 0);
      
      // register sensitive detector
      tmp = "BBarrel_" + G4UIcommand::ConvertToString(i);
      BBarrel_sensitive_detector[i] = new SensitiveDetector(tmp, SensitiveDetectorIndex, data);
      SDman->AddNewDetector(BBarrel_sensitive_detector[i]);
      bbarrel_log[i]->SetSensitiveDetector(BBarrel_sensitive_detector[i]);
#ifdef G4VIS_USE
      if(!data->Coulex){
	if((data->Cut&(1<<2)) && i == 1) //was i==3
	  bbarrel_log[i]->SetVisAttributes(hbBDVisAtt);
	else
	  bbarrel_log[i]->SetVisAttributes(bBDVisAtt);
      }
      else{
	bbarrel_log[i]->SetVisAttributes(hbBDVisAtt);
      }
#endif
      SensitiveDetectorIndex++;
       if(data->VerboseLevel > 1)
	cout<<"DetectorConstruction: created bBarrel "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
      
      if(data->BarrelType == 1){
	tmp = "bebarrel_log_" + G4UIcommand::ConvertToString(i);
	bebarrel_log[i] = new G4LogicalVolume(bebarrel_solid[i], Silicon, tmp);
	
	tmp = "bebarrel_" + G4UIcommand::ConvertToString(i);
	position.set(x*(data->settings->BarrelDistance+data->settings->PCBThickness+data->settings->BarrelDeltaEGap-data->settings->beBarrelThickness[i]/2.),y*(data->settings->BarrelDistance+data->settings->PCBThickness+data->settings->BarrelDeltaEGap-data->settings->beBarrelThickness[i]/2.),data->settings->BackwardBarrelZ);
	berotation[i] = new G4RotationMatrix();
	berotation[i]->rotateZ(angle);
	
	new G4PVPlacement(berotation[i], position, tmp, bebarrel_log[i], mother, false, 0);
	
	// register sensitive detector
	tmp = "BEBarrel_" + G4UIcommand::ConvertToString(i);
	BEBarrel_sensitive_detector[i] = new SensitiveDetector(tmp, SensitiveDetectorIndex, data);
	SDman->AddNewDetector(BEBarrel_sensitive_detector[i]);
	bebarrel_log[i]->SetSensitiveDetector(BEBarrel_sensitive_detector[i]);
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<2)) && i == 1)
	    bebarrel_log[i]->SetVisAttributes(hbBDEVisAtt);
	  else
	    bebarrel_log[i]->SetVisAttributes(bBDEVisAtt);
	}
	else
	  bebarrel_log[i]->SetVisAttributes(hbBDEVisAtt);
#endif
	SensitiveDetectorIndex++;
	if(data->VerboseLevel > 1)
	  cout<<"DetectorConstruction: created beBarrel "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
      }//barreltype ==1
      ///////////////////////////////////////////////
      
      
      //PCB boards
      //forward deltaE
      if(!(data->Cut&(1<<7))){
	tmp = "fPCB_log_" + G4UIcommand::ConvertToString(i);
	fPCB_log[i] = new G4LogicalVolume(deltaPCB_solid, PCB, tmp);
	
	tmp = "fPCB_" + G4UIcommand::ConvertToString(i);
	position.set(x_pcb+x*data->settings->PCBThickness/2.,y_pcb+y*data->settings->PCBThickness/2.,data->settings->ForwardBarrelZ-(data->settings->PCBLength-data->settings->BarrelLength)/2.);
	fpcbrotation[i] = new G4RotationMatrix();
	fpcbrotation[i]->rotateZ(angle+180.*degree);
	new G4PVPlacement(fpcbrotation[i], position, tmp, fPCB_log[i], mother, false, 0);
	
	if(data->VerboseLevel > 1){
	  cout<<"DetectorConstruction: created fPCB "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
	}

#ifdef G4VIS_USE
	if((data->Cut&(1<<2)) && i == 1)
	  fPCB_log[i]->SetVisAttributes(*hfBDPCBVisAtt);
	else	    
	  fPCB_log[i]->SetVisAttributes(*fBDPCBVisAtt);
	if(data->Cut&(1<<5))
	  fPCB_log[i]->SetVisAttributes(*hfBDPCBVisAtt);
	  
#endif
		
	//backward
	tmp = "bPCB_log_" + G4UIcommand::ConvertToString(i);
	bPCB_log[i] = new G4LogicalVolume(deltaPCB_solid, PCB, tmp);
	
	tmp = "bPCB_" + G4UIcommand::ConvertToString(i);
	position.set(-(x_pcb+x*data->settings->PCBThickness/2.),y_pcb+y*data->settings->PCBThickness/2.,data->settings->BackwardBarrelZ+(data->settings->PCBLength-data->settings->BarrelLength)/2.);
	//position.set(x_pcb_b+x*data->settings->PCBThickness/2.,y_pcb_b+y*data->settings->PCBThickness/2.,data->settings->BackwardBarrelZ+(data->settings->PCBLength-data->settings->BarrelLength)/2.);
	bpcbrotation[i] = new G4RotationMatrix();
	bpcbrotation[i]->rotateX(180.*degree);
	bpcbrotation[i]->rotateZ(angle);
	new G4PVPlacement(bpcbrotation[i], position, tmp, bPCB_log[i], mother, false, 0);
	
	if(data->VerboseLevel > 1){
	  cout<<"DetectorConstruction: created bPCB "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
	}
	
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<2)) && i == 3)
	    bPCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	  else	    
	    bPCB_log[i]->SetVisAttributes(*bBDPCBVisAtt);
	  if(data->Cut&(1<<5))
	    bPCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	  //else	    
	  //  bPCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	}
	else
	  bPCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
#endif
	

	//forward E
	tmp = "fePCB_log_" + G4UIcommand::ConvertToString(i);
	fePCB_log[i] = new G4LogicalVolume(EPCB_solid, PCB, tmp);
	
	tmp = "fePCB_" + G4UIcommand::ConvertToString(i);
	position.set(x_pcb+x*(data->settings->BarrelDeltaEGap+3*data->settings->PCBThickness/2.),y_pcb+y*(data->settings->BarrelDeltaEGap+3*data->settings->PCBThickness/2.),data->settings->ForwardBarrelZ-(data->settings->PCBLength-data->settings->BarrelLength)/2.);
	fepcbrotation[i] = new G4RotationMatrix();
	fepcbrotation[i]->rotateZ(angle+180.*degree);
	
	new G4PVPlacement(fepcbrotation[i], position, tmp, fePCB_log[i], mother, false, 0);
	
	if(data->VerboseLevel > 1){
	  cout<<"DetectorConstruction: created fePCB "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
	}
	
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<2)) && i == 1)
	    fePCB_log[i]->SetVisAttributes(*hfBDPCBVisAtt);
	  else	    
	    fePCB_log[i]->SetVisAttributes(*fBDPCBVisAtt);
	  if(data->Cut&(1<<5))
	    fePCB_log[i]->SetVisAttributes(*hfBDPCBVisAtt);
	}
	else
	  fePCB_log[i]->SetVisAttributes(*hfBDPCBVisAtt);
#endif
	//////////////////////////////////////
	//backward E PCB
	if(data->BarrelType == 1){
	  
	  tmp = "bePCB_log_" + G4UIcommand::ConvertToString(i);
	  bePCB_log[i] = new G4LogicalVolume(EPCB_solid, PCB, tmp);
	  
	  tmp = "bePCB_" + G4UIcommand::ConvertToString(i);
	  position.set(-(x_pcb+x*(data->settings->BarrelDeltaEGap+3*data->settings->PCBThickness/2.)),y_pcb+y*(data->settings->BarrelDeltaEGap+3*data->settings->PCBThickness/2.),data->settings->BackwardBarrelZ+(data->settings->PCBLength-data->settings->BarrelLength)/2.);
	  bepcbrotation[i] = new G4RotationMatrix();
	  bepcbrotation[i]->rotateX(180.*degree);
	  bepcbrotation[i]->rotateZ(angle);
	  new G4PVPlacement(bepcbrotation[i], position, tmp, bePCB_log[i], mother, false, 0);
	  
	  if(data->VerboseLevel > 1){
	    cout<<"DetectorConstruction: created bePCB "<<i<<" at position ("<<position.x()<<","<<position.y()<<","<<position.z()<<") rotated by "<<angle/degree<<" degree around z"<<endl;
	  }
	  
#ifdef G4VIS_USE
	if(!data->Coulex){
	  if((data->Cut&(1<<2)) && i == 3)
	    bePCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	  else	    
	    bePCB_log[i]->SetVisAttributes(*bBDPCBVisAtt);
	  if(data->Cut&(1<<5))
	    bePCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	}
	else{
	  bePCB_log[i]->SetVisAttributes(*hbBDPCBVisAtt);
	}
#endif
	}
      }//if(!data->Cut&(1<<7))
    }//nof quadrants
  }
  // definition of target_material
  G4Material* TargetMaterial;
  if(data->settings->TargetMaterialZ > 0)
    {
      //if target isotope is the same as the target material name the target consists of only that isotope
      if(data->settings->TargetMaterialName == data->TargetName)
	{
	  if(data->VerboseLevel > 1)
	    cout<<"creating target ("<<data->settings->TargetMaterialName<<") with Z = "<<data->settings->TargetMaterialZ<<", Mole = "<<data->settings->TargetMaterialMole/(g/mole)<<" and TargetMaterialDensity = "<<data->settings->TargetMaterialDensity/(g/cm3)<<endl;
	  
	  TargetMaterial = new G4Material(data->settings->TargetMaterialName, data->settings->TargetMaterialZ, data->settings->TargetMaterialMole, data->settings->TargetMaterialDensity);
	}
      //if target isotope != target material name => target consists of target material name + target isotope, e.g. titanium and tritons
      else
	{
	  if(data->VerboseLevel > 1)
	    cout<<"creating target ("<<data->settings->TargetMaterialName<<") with Z = "<<data->settings->TargetMaterialZ<<", Mole = "<<data->settings->TargetMaterialMole/(g/mole)<<" and TargetMaterialDensity = "<<data->settings->TargetMaterialDensity/(g/cm3)<<", and with "<<data->TargetName<<endl;
	  

	  G4Element* Carrier;
	  G4Element* Target;
	  
	  G4String tmp;
	  tmp = data->settings->TargetMaterialName;
	  tmp.remove(0,tmp.find_first_not_of("0123456789"));
	  Carrier = NistManager->FindOrBuildElement(tmp);

	  tmp = data->TargetName;
	  tmp.remove(0,tmp.find_first_not_of("0123456789"));
	  Target =  NistManager->FindOrBuildElement(tmp);
	  
	  TargetMaterial = new G4Material(data->settings->TargetMaterialName, data->settings->TargetMaterialDensity, 2);
	  TargetMaterial->AddElement(Carrier,1-data->TargetRatio);
	  TargetMaterial->AddElement(Target,data->TargetRatio);

	  TargetMaterial = new G4Material(data->settings->TargetMaterialName, data->settings->TargetMaterialZ, data->settings->TargetMaterialMole, data->settings->TargetMaterialDensity);
	}
    }
  else if(data->settings->TargetMaterialName.contains("PE"))
    {
      if(data->VerboseLevel > 1)
	cout<<"creating PE target ("<<data->settings->TargetMaterialName<<")"<<endl;

      G4Element* C;
      G4Element* D;
      G4Element* H;
      if(isalpha(data->settings->TargetMaterialName.data()[0]))
	{
	  if(data->VerboseLevel > 2)
	    cout<<"creating PE target ("<<data->settings->TargetMaterialName<<") with 100% deuterium"<<endl;

	  C = new G4Element("Carbon", "C", 6., 12.000*g/mole);
	  D = new G4Element("Deuterium", "D", 1., 2.014*g/mole);
	  TargetMaterial = new G4Material("PE", data->settings->TargetMaterialDensity, 2);
	  TargetMaterial->AddElement(C,1);
	  TargetMaterial->AddElement(D,2);
	}
      else
	{
	  G4double ratio = atof(data->settings->TargetMaterialName.data());
	  if(ratio < 0 || ratio > 1)
	    {
	      cout<<"Error, only ratios between 0 and 1 are allowed, tried to build "<<data->settings->TargetMaterialName<<" with deuteron/proton ratio = "<<ratio<<endl;
	      exit(1);
	    }
	  if(ratio == 0)
	    {
	      if(data->VerboseLevel > 2)
		cout<<"creating PE target ("<<data->settings->TargetMaterialName<<") with 100% hydrogen"<<endl;

	      C = new G4Element("Carbon", "C", 6., 12.000*g/mole);
	      H = new G4Element("Hydrogen", "H", 1., 1.008*g/mole);
	      TargetMaterial = new G4Material("PE", data->settings->TargetMaterialDensity, 2);
	      TargetMaterial->AddElement(C,1);
	      TargetMaterial->AddElement(H,2);
	    }
	  else if(ratio == 1)
	    {
	      if(data->VerboseLevel > 2)
		cout<<"creating PE target ("<<data->settings->TargetMaterialName<<") with 100% deuterium"<<endl;

	      C = new G4Element("Carbon", "C", 6., 12.000*g/mole);
	      D = new G4Element("Deuterium", "D", 1., 2.014*g/mole);
	      TargetMaterial = new G4Material("PE", data->settings->TargetMaterialDensity, 2);
	      TargetMaterial->AddElement(C,1);
	      TargetMaterial->AddElement(D,2);
	    }
	  else
	    {
	      if(data->VerboseLevel > 2)
		cout<<"creating PE target ("<<data->settings->TargetMaterialName<<") with "<<(G4int)(100*(1-ratio))<<"% hydrogen and "<<(G4int)(100*ratio)<<"% deuterium (ratio = "<<ratio<<")"<<endl;

	      C = new G4Element("Carbon", "C", 6., 12.000*g/mole);
	      D = new G4Element("Deuterium", "D", 1., 2.014*g/mole);
	      H = new G4Element("Hydrogen", "H", 1., 1.008*g/mole);
	      TargetMaterial = new G4Material("PE", data->settings->TargetMaterialDensity, 3);
	      TargetMaterial->AddElement(C,12.000/(12.000+(1-ratio)*1.008+ratio*2.014));
	      TargetMaterial->AddElement(D,ratio*2.014/(12.000+(1-ratio)*1.008+ratio*2.014));
	      TargetMaterial->AddElement(H,(1-ratio)*1.008/(12.000+(1-ratio)*1.008+ratio*2.014));
	      cout<<"created PE with mass ratios: C = "<<12.000/(12.000+(1-ratio)*1.008+ratio*2.014)<<", D = "<<2.014/(12.000+(1-ratio)*1.008+ratio*2.014)<<" and H = "<<1.008/(12.000+(1-ratio)*1.008+ratio*2.014)<<endl;
	    }
	}
    }
  else
    {
      cerr<<"Sorry TargetMaterial "<<data->settings->TargetMaterialName<<"not implemented yet!\n";
      exit(1);
    }
  
  TargetMaterialVisAtt->SetVisibility(true);
  
  //construct target
  G4Tubs* target_solid;
  G4LogicalVolume* target_log;
  G4RotationMatrix* target_rotation = new G4RotationMatrix();
  target_rotation->rotateX(data->settings->TargetAngle);

  if(data->VerboseLevel > 2)
    {
      cout<<"Using TargetMaterial "<<TargetMaterial->GetName()<<":"<<endl
	  <<"\tChemical Formula "<<TargetMaterial->GetChemicalFormula()<<endl
	  <<"\tDensity = "<<TargetMaterial->GetDensity()/(g/cm3)<<" g/cm3"<<endl
	  <<"\tNumber of Elements = "<<TargetMaterial->GetNumberOfElements()<<endl;
      for(i=0;i<((G4int) TargetMaterial->GetNumberOfElements());i++)
	{
	  cout<<"\t\tElement "<<i<<": "<<TargetMaterial->GetElement(i)->GetName()<<endl;
	}
      cout<<"\tNuclear Interaction Length = "<<TargetMaterial->GetNuclearInterLength()/micrometer<<" um"<<endl;
    }
  
  target_solid = new G4Tubs("target_solid", 0, data->settings->TargetRadius, (data->settings->TargetThickness)/(data->settings->TargetMaterialDensity)/2., 0, 2*M_PI);
  target_log = new G4LogicalVolume(target_solid, TargetMaterial, "target_log");
  
  cout << " target thicknes " << (data->settings->TargetThickness)/(data->settings->TargetMaterialDensity)/2. << endl;

  if(data->AlphaSource  || data->QuadAlphaSource)
    new G4PVPlacement(0, G4ThreeVector(0, 0, 0), "target", target_log, mother, false, 0);
  else{
    new G4PVPlacement(0, G4ThreeVector(0, 0, data->settings->TargetShift[2]), "target", target_log, mother, false, 0);
    cout << "-----------------------------------------------------------"<<endl;
    cout << "data->settings->TargetShift " << data->settings->TargetShift << endl;
    cout << "-----------------------------------------------------------"<<endl;
  }
  target_log->SetVisAttributes(TargetMaterialVisAtt);

  //chamber
  if(data->ChamberType == 1 || data->ChamberType == 2 || data->ChamberType == 3)
    {
      G4double z[6] = {data->settings->ChamberLength/2., data->settings->ChamberLength/2. - data->settings->ChamberBackThickness, data->settings->ChamberLength/2. - data->settings->ChamberBackThickness, -(data->settings->ChamberLength/2. - data->settings->ChamberFrontThickness), -(data->settings->ChamberLength/2. - data->settings->ChamberFrontThickness), -data->settings->ChamberLength/2.};
      G4double inner_r[6] = {data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius};
      G4double outer_r[6] = {data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness};
      
      G4Polycone* chamber_solid;
      if(data->Cut&1)
	{
	  chamber_solid = new G4Polycone("ChamberSolid", 90.*degree, 180.*degree, 6, z, inner_r, outer_r);
	}
      else
	{
	  chamber_solid = new G4Polycone("ChamberSolid", 0.*degree, 360.*degree, 6, z, inner_r, outer_r);
	}

      G4LogicalVolume* chamber_log = new G4LogicalVolume(chamber_solid, Aluminum, "ChamberLog");
      
      if(data->ChamberType != 2) //middle long cylindrical Chamber is not placed at origin
	{
	  new G4PVPlacement(0, G4ThreeVector(0,0,0), "Chamber", chamber_log, mother, false, 0);
	}
      else
	{
	  new G4PVPlacement(0, G4ThreeVector(0,0,-(data->settings->ChamberLength/2.-70.*mm)), "Chamber", chamber_log, mother, false, 0);
	}
      
      
      
      chamber_log->SetVisAttributes(ChamberVisAtt);
    }
  else if(data->ChamberType == 4)
    {
      if(data->VerboseLevel > 3)
	cout<<"starting construction of spherical Chamber"<<endl;

      //the sphere
      G4Sphere* chamber_sphere;
      if(data->Cut&1)
	{
	  chamber_sphere = new G4Sphere("ChamberSphere", data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, 90.*degree, 180.*degree, asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius), 180.*degree - asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius) - asin(data->settings->ChamberForwardFlangeInnerRadius/data->settings->ChamberInnerRadius));
	  if(data->VerboseLevel > 3)
	    cout<<"sphere(ChamberSphere, "<<data->settings->ChamberInnerRadius<<", "<<data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness<<", 90.*degree, 180.*degree, "<<(asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius))/degree<<", "<<(180.*degree - asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius) - asin(data->settings->ChamberForwardFlangeInnerRadius/data->settings->ChamberInnerRadius))/degree<<"), asin("<<data->settings->ChamberForwardFlangeInnerRadius<<"/"<<data->settings->ChamberInnerRadius<<"), asin("<<data->settings->ChamberBackwardFlangeInnerRadius<<"/"<<data->settings->ChamberInnerRadius<<")"<<endl;
	}
      else
	{
	  chamber_sphere = new G4Sphere("ChamberSphere", data->settings->ChamberInnerRadius, data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness, 0.*degree, 360.*degree, asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius), 180.*degree - asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius) - asin(data->settings->ChamberForwardFlangeInnerRadius/data->settings->ChamberInnerRadius));
	  if(data->VerboseLevel > 3)
	    cout<<"sphere(ChamberSphere, "<<data->settings->ChamberInnerRadius<<", "<<data->settings->ChamberInnerRadius + data->settings->ChamberWallThickness<<", 0.*degree, 360.*degree, "<<(asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius))/degree<<", "<<(180.*degree - asin(data->settings->ChamberBackwardFlangeInnerRadius/data->settings->ChamberInnerRadius) - asin(data->settings->ChamberForwardFlangeInnerRadius/data->settings->ChamberInnerRadius))/degree<<"), asin("<<data->settings->ChamberForwardFlangeInnerRadius<<"/"<<data->settings->ChamberInnerRadius<<"), asin("<<data->settings->ChamberBackwardFlangeInnerRadius<<"/"<<data->settings->ChamberInnerRadius<<")"<<endl;
	}

      //flanges and connections to flanges
      G4Polycone* forward_flange;
      G4Polycone* backward_flange;

      G4double forward_flange_z[4] = {0,-data->settings->ChamberForwardFlangeConnectionLength,-data->settings->ChamberForwardFlangeConnectionLength,-(data->settings->ChamberForwardFlangeConnectionLength+data->settings->ChamberForwardFlangeLength)};
      G4double forward_flange_inner_radius[4] = {data->settings->ChamberForwardFlangeInnerRadius,data->settings->ChamberForwardFlangeInnerRadius,data->settings->ChamberForwardFlangeInnerRadius,data->settings->ChamberForwardFlangeInnerRadius};
      G4double forward_flange_outer_radius[4] = {data->settings->ChamberForwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness,data->settings->ChamberForwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness,data->settings->ChamberForwardFlangeOuterRadius,data->settings->ChamberForwardFlangeOuterRadius};

      G4double backward_flange_z[4] = {0,data->settings->ChamberBackwardFlangeConnectionLength,data->settings->ChamberBackwardFlangeConnectionLength,data->settings->ChamberBackwardFlangeConnectionLength+data->settings->ChamberBackwardFlangeLength};
      G4double backward_flange_inner_radius[4] = {data->settings->ChamberBackwardFlangeInnerRadius,data->settings->ChamberBackwardFlangeInnerRadius,data->settings->ChamberBackwardFlangeInnerRadius,data->settings->ChamberBackwardFlangeInnerRadius};
      G4double backward_flange_outer_radius[4] = {data->settings->ChamberBackwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness,data->settings->ChamberBackwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness,data->settings->ChamberBackwardFlangeOuterRadius,data->settings->ChamberBackwardFlangeOuterRadius};

      if(data->VerboseLevel > 3)
	{
	  cout<<"forward flange: z = 0,"<<-data->settings->ChamberForwardFlangeConnectionLength<<","<<-data->settings->ChamberForwardFlangeConnectionLength<<","<<-(data->settings->ChamberForwardFlangeConnectionLength+data->settings->ChamberForwardFlangeLength)<<endl
	      <<"\t r_i = "<<data->settings->ChamberForwardFlangeInnerRadius<<","<<data->settings->ChamberForwardFlangeInnerRadius<<","<<data->settings->ChamberForwardFlangeInnerRadius<<","<<data->settings->ChamberForwardFlangeInnerRadius<<endl
	      <<"\t r_o = "<<data->settings->ChamberForwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness<<","<<data->settings->ChamberForwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness<<","<<data->settings->ChamberForwardFlangeOuterRadius<<","<<data->settings->ChamberForwardFlangeOuterRadius<<endl;

	  cout<<"backward flange: z = 0,"<<data->settings->ChamberBackwardFlangeConnectionLength<<","<<data->settings->ChamberBackwardFlangeConnectionLength<<","<<data->settings->ChamberBackwardFlangeConnectionLength+data->settings->ChamberBackwardFlangeLength<<endl
	      <<"\t r_i = "<<data->settings->ChamberBackwardFlangeInnerRadius<<","<<data->settings->ChamberBackwardFlangeInnerRadius<<","<<data->settings->ChamberBackwardFlangeInnerRadius<<","<<data->settings->ChamberBackwardFlangeInnerRadius<<endl
	      <<"\t r_o = "<<data->settings->ChamberBackwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness<<","<<data->settings->ChamberBackwardFlangeInnerRadius+data->settings->ChamberFlangeConnectionThickness<<","<<data->settings->ChamberBackwardFlangeOuterRadius<<","<<data->settings->ChamberBackwardFlangeOuterRadius<<endl;
	}

      //flanges
      if(data->Cut&1)
	{
	  forward_flange = new G4Polycone("forward_flange",90.*degree,M_PI,4,forward_flange_z,forward_flange_inner_radius,forward_flange_outer_radius);
	  backward_flange = new G4Polycone("backward_flange",90.*degree,M_PI,4,backward_flange_z,backward_flange_inner_radius,backward_flange_outer_radius);
	}
      else
	{
	  forward_flange = new G4Polycone("forward_flange",0.,2*M_PI,4,forward_flange_z,forward_flange_inner_radius,forward_flange_outer_radius);
	  backward_flange = new G4Polycone("backward_flange",0.,2*M_PI,4,backward_flange_z,backward_flange_inner_radius,backward_flange_outer_radius);
	}

      //union of sphere with forward flange
      G4UnionSolid* tmp_solid;
      tmp_solid = new G4UnionSolid("tmp_solid",chamber_sphere,forward_flange,new G4RotationMatrix(),G4ThreeVector(0,0,-sqrt(pow(data->settings->ChamberInnerRadius,2)-pow(data->settings->ChamberForwardFlangeInnerRadius,2))));

      if(data->VerboseLevel > 3)
	cout<<"union(tmp_solid,chamber_sphere,forward_flange,new G4RotationMatrix(),G4ThreeVector(0,0,"<<-sqrt(pow(data->settings->ChamberInnerRadius,2)-pow(data->settings->ChamberForwardFlangeInnerRadius,2))<<")"<<endl;

      //union of sphere with backward flange
      G4UnionSolid* chamber_with_flanges;
      chamber_with_flanges = new G4UnionSolid("chamber_with_flanges",tmp_solid,backward_flange,new G4RotationMatrix(),G4ThreeVector(0,0,sqrt(pow(data->settings->ChamberInnerRadius,2)-pow(data->settings->ChamberBackwardFlangeInnerRadius,2))));

      if(data->VerboseLevel > 3)
	cout<<"union(chamber_with_flanges,tmp_solid,backward_flange,new G4RotationMatrix(),G4ThreeVector(0,0,"<<sqrt(pow(data->settings->ChamberInnerRadius,2)-pow(data->settings->ChamberBackwardFlangeInnerRadius,2))<<")"<<endl;

      //hole for target flange
      G4Tubs* hole;
      hole = new G4Tubs("hole",0,data->settings->ChamberTargetFlangeInnerRadius,5*data->settings->ChamberWallThickness,0.,2*M_PI);

      //target flange
      G4Polycone* target_flange;

      G4double target_flange_z[4] = {0,-(data->settings->ChamberTargetFlangeConnectionLength-sin(20.*degree)*(data->settings->ChamberTargetFlangeOuterRadius - data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness)),-data->settings->ChamberTargetFlangeConnectionLength,-(data->settings->ChamberTargetFlangeConnectionLength+data->settings->ChamberTargetFlangeLength)};
      G4double target_flange_inner_radius[4] = {data->settings->ChamberTargetFlangeInnerRadius,data->settings->ChamberTargetFlangeInnerRadius,data->settings->ChamberTargetFlangeInnerRadius,data->settings->ChamberTargetFlangeInnerRadius};
      G4double target_flange_outer_radius[4] = {data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness,data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness,data->settings->ChamberTargetFlangeOuterRadius,data->settings->ChamberTargetFlangeOuterRadius};

      if(data->VerboseLevel > 3)
	{
	  cout<<"target flange: z = 0,"<<-(data->settings->ChamberTargetFlangeConnectionLength-sin(20.*degree)*(data->settings->ChamberTargetFlangeOuterRadius - data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness))<<","<<-data->settings->ChamberTargetFlangeConnectionLength<<","<<-(data->settings->ChamberTargetFlangeConnectionLength+data->settings->ChamberTargetFlangeLength)<<endl
	      <<"\t r_i = "<<data->settings->ChamberTargetFlangeInnerRadius<<","<<data->settings->ChamberTargetFlangeInnerRadius<<","<<data->settings->ChamberTargetFlangeInnerRadius<<","<<data->settings->ChamberTargetFlangeInnerRadius<<endl
	      <<"\t r_o = "<<data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness<<","<<data->settings->ChamberTargetFlangeInnerRadius+data->settings->ChamberWallThickness<<","<<data->settings->ChamberTargetFlangeOuterRadius<<","<<data->settings->ChamberTargetFlangeOuterRadius<<endl;
	}

      if(data->Cut&1)
	{
	  target_flange = new G4Polycone("target_flange",90.*degree,M_PI,4,target_flange_z,target_flange_inner_radius,target_flange_outer_radius);
	}
      else
	{
	  target_flange = new G4Polycone("target_flange",0.,2*M_PI,4,target_flange_z,target_flange_inner_radius,target_flange_outer_radius);
	}

      //cut hole into sphere
      G4RotationMatrix* rotate_target_flange;
      rotate_target_flange = new G4RotationMatrix();
      rotate_target_flange->rotateX(90.*degree);

      G4SubtractionSolid* chamber_with_hole;
      chamber_with_hole = new G4SubtractionSolid("chamber_with_hole", chamber_with_flanges, hole, rotate_target_flange, G4ThreeVector(0,-(data->settings->ChamberInnerRadius+data->settings->ChamberWallThickness)+2.*data->settings->ChamberWallThickness,0));

      if(data->VerboseLevel > 3)
	cout<<"subtraction: sphere - hole, hole (radius = "<<data->settings->ChamberTargetFlangeInnerRadius<<", thickness = "<<5*data->settings->ChamberWallThickness<<") at (0,"<<-(data->settings->ChamberInnerRadius+data->settings->ChamberWallThickness)+2.*data->settings->ChamberWallThickness<<",0)"<<endl;

      //union of sphere with target flange
      G4UnionSolid* chamber_solid;
      chamber_solid = new G4UnionSolid("chamber_solid",chamber_with_hole,target_flange,rotate_target_flange,G4ThreeVector(0,-sqrt(pow((data->settings->ChamberInnerRadius+data->settings->ChamberWallThickness),2)-pow(data->settings->ChamberTargetFlangeOuterRadius,2)),0));

      if(data->VerboseLevel > 3)
	cout<<"added target flange at (0,"<<-sqrt(pow((data->settings->ChamberInnerRadius+data->settings->ChamberWallThickness),2)-pow(data->settings->ChamberTargetFlangeOuterRadius,2))<<",0)"<<endl;

      G4LogicalVolume* chamber_log = new G4LogicalVolume(chamber_solid, Aluminum, "chamber_log");
      new G4PVPlacement(0, G4ThreeVector(0,0,0), "Chamber", chamber_log, mother, false, 0);
      
      chamber_log->SetVisAttributes(ChamberVisAtt);
    }

  else if(data->ChamberType == 5 || data->ChamberType == 6){
    G4Tubs *chamber_tubs;
    G4Cons *chamber_cons1;
    G4Cons *chamber_cons2;

    G4Tubs *chamber_tubs1;
    G4Tubs *chamber_tubs2;
    G4Tubs *chamber_tubs3;
    G4UnionSolid *chamber_01;
    G4UnionSolid *chamber_012;
    G4UnionSolid *chamber_tubstot;

    G4UnionSolid* chamber_solid;
    G4UnionSolid* chamber_cons;

    if(data->Cut&1){
      chamber_tubs = new G4Tubs("ChamberTubs",70.*mm,72.*mm,62.*mm,90.*degree,180.*degree);
      chamber_tubs1 = new G4Tubs("ChamberTubs1",70.*mm,72.*mm,34.*mm,90.*degree,180.*degree);
      chamber_tubs2 = new G4Tubs("ChamberTubs2",70.*mm,90.*mm,62.5*mm,90.*degree,180.*degree);
      chamber_tubs3 = new G4Tubs("ChamberTubs3",51.*mm,54.*mm,41.5*mm,90.*degree,180.*degree);
      chamber_cons1 = new G4Cons("ChamberCons1",59.*mm,61.*mm,70.*mm,72.*mm,10.*mm,90.*degree,180.*degree);
      chamber_cons2 = new G4Cons("ChamberCons2",12.5*mm,14.5*mm,59.*mm,61.*mm,9.5*mm,90.*degree,180.*degree);
    }
    else{
      chamber_tubs = new G4Tubs("ChamberTubs",70.*mm,72.*mm,62.*mm,0.*degree,360.*degree);
      chamber_tubs1 = new G4Tubs("ChamberTubs1",70.*mm,72.*mm,34.*mm,0.*degree,360.*degree);
      chamber_tubs2 = new G4Tubs("ChamberTubs2",70.*mm,90.*mm,62.5*mm,0.*degree,360.*degree);
      chamber_tubs3 = new G4Tubs("ChamberTubs3",51.*mm,54.*mm,41.5*mm,0.*degree,360.*degree);
      chamber_cons1 = new G4Cons("ChamberCons1",59.*mm,61.*mm,70.*mm,72.*mm,10.*mm,0.*degree,360.*degree);
      chamber_cons2 = new G4Cons("ChamberCons2",12.5*mm,14.5*mm,59.*mm,61.*mm,9.5*mm,0.*degree,360.*degree);
    }

    chamber_01 = new G4UnionSolid("chamber_01", chamber_tubs, chamber_tubs1, new G4RotationMatrix(),G4ThreeVector(0,0,96.05*mm)); 
    chamber_012 = new G4UnionSolid("chamber_012", chamber_01, chamber_tubs2, new G4RotationMatrix(),G4ThreeVector(0,0,158.55*mm)); 
    //chamber_tubstot = new G4UnionSolid("chamber_tubstot", chamber_012, chamber_tubs3, new G4RotationMatrix(),G4ThreeVector(0,0,200.05*mm)); 
    chamber_cons = new G4UnionSolid("chamber_cons", chamber_cons1, chamber_cons2, new G4RotationMatrix(),G4ThreeVector(0,0,-19.5*mm)); 
    if(data->ChamberType == 6)
      chamber_solid = new G4UnionSolid("chamber_solid", chamber_012, chamber_cons, new G4RotationMatrix(),G4ThreeVector(0,0,-72.05*mm));
    else
      chamber_solid = new G4UnionSolid("chamber_solid", chamber_tubs, chamber_cons, new G4RotationMatrix(),G4ThreeVector(0,0,-72.05*mm));
      
    
    G4LogicalVolume* chamber_log = new G4LogicalVolume(chamber_solid, Aluminum, "chamber_log");
    new G4PVPlacement(0, G4ThreeVector(0,0,0), "Chamber", chamber_log, mother, false, 0);
    
    chamber_log->SetVisAttributes(ChamberVisAtt);
    /*
    G4LogicalVolume* chamber_logtest = new G4LogicalVolume(chamber_01, Aluminum, "chamber_logtest");
    new G4PVPlacement(0, G4ThreeVector(0,0,0), "Chambertest", chamber_logtest, mother, false, 0);
    
    chamber_logtest->SetVisAttributes(fBDPCBVisAtt);
    */
  }



  else if(data->ChamberType == 10)
    {
      G4Sphere* chamber_solid;
      if(data->Cut&1)
	{
	  chamber_solid = new G4Sphere("ChamberSolid", 83.*mm, 85.*mm, 90.*degree, 180.*degree, 15.*degree, 150.*degree);
	}
      else
	{
	  chamber_solid = new G4Sphere("ChamberSolid", 83.*mm, 85.*mm, 0.*degree, 360.*degree, 15.*degree, 150.*degree);
	}
      G4LogicalVolume* chamber_log = new G4LogicalVolume(chamber_solid, Aluminum, "chamber_log");
      new G4PVPlacement(0, G4ThreeVector(0,0,0), "Chamber", chamber_log, mother, false, 0);
      
      chamber_log->SetVisAttributes(ChamberVisAtt);
    }

  //screening
  if(data->Screening){
    if(et != 2){
      G4Tubs* cd_foil[2];
      G4LogicalVolume* cd_foil_log[2];
      if(et==0 || et==4){//ForwardCD
	
	if(data->VerboseLevel > 3){
	  cout<<"creating forward CD screening foil with r_i = "<<data->settings->CDFoilInnerRadius/mm<<" mm, r_o = "<<data->settings->CDFoilOuterRadius/mm<<" mm, thickness = "<<data->settings->FCDFoilThickness/micrometer<<" um"<<endl;
	}
	if(data->Cut&(1<<3)){
	  cd_foil[0] = new G4Tubs("cd_screening",data->settings->CDFoilInnerRadius,data->settings->CDFoilOuterRadius,data->settings->FCDFoilThickness/2.,90.*degree,M_PI);
	}
	else{
	  cd_foil[0] = new G4Tubs("cd_screening",data->settings->CDFoilInnerRadius,data->settings->CDFoilOuterRadius,data->settings->FCDFoilThickness/2.,0.,2*M_PI);
	}
	
	if(data->ScreeningMaterialName.contains("aluminum")){
	  cd_foil_log[0] = new G4LogicalVolume(cd_foil[0], Aluminum, "cd_foil_log");
	}
	else if(data->ScreeningMaterialName.contains("mylar")){
	  cd_foil_log[0] = new G4LogicalVolume(cd_foil[0], Mylar, "cd_foil_log");
	}
	else{
	  cerr<<"ERROR in DetectorConstruction: ScreeningMaterialName "<<data->ScreeningMaterialName<<" is unknown!"<<endl;
	  exit(1);
	}

	new G4PVPlacement(0, G4ThreeVector(0,0,data->settings->SSDZPosition-data->settings->CDFoilDistance-data->settings->FCDFoilThickness/2.-data->settings->SSDPCBStripThickness), "FCDScreening", cd_foil_log[0], mother, false, 0);
	
	cd_foil_log[0]->SetVisAttributes(FCDFoilVisAtt);

      }// forward cd
      if(et==1 || (et>2 && data->BackwardFoil ==3) ){//backwardCD
	if(data->VerboseLevel > 3){
	  cout<<"creating backward CD screening foil with r_i = "<<data->settings->CDFoilInnerRadius/mm<<" mm, r_o = "<<data->settings->CDFoilOuterRadius/mm<<" mm, thickness = "<<data->settings->BCDFoilThickness/micrometer<<" um"<<endl;
	}
	if(data->Cut&(1<<3)){
	  cd_foil[et/4] = new G4Tubs("cd_screening",data->settings->CDFoilInnerRadius,data->settings->CDFoilOuterRadius,data->settings->BCDFoilThickness/2.,90.*degree,M_PI);
	}
	else{
	  cd_foil[et/4] = new G4Tubs("cd_screening",data->settings->CDFoilInnerRadius,data->settings->CDFoilOuterRadius,data->settings->BCDFoilThickness/2.,0.,2*M_PI);
	}
	
	if(data->ScreeningMaterialName.contains("aluminum")){
	  cd_foil_log[et/4] = new G4LogicalVolume(cd_foil[et/4], Aluminum, "cd_foil_log");
	}
	else if(data->ScreeningMaterialName.contains("mylar")){
	  cd_foil_log[et/4] = new G4LogicalVolume(cd_foil[et/4], Mylar, "cd_foil_log");
	}
	else{
	  cerr<<"ERROR in DetectorConstruction: ScreeningMaterialName "<<data->ScreeningMaterialName<<" is unknown!"<<endl;
	  exit(1);
	}
	new G4PVPlacement(0, G4ThreeVector(0,0,-(data->settings->SSDZPosition-data->settings->CDFoilDistance-data->settings->BCDFoilThickness/2.-data->settings->SSDPCBStripThickness)), "BCDScreening", cd_foil_log[et/4], mother, false, 0);
	
	cd_foil_log[et/4]->SetVisAttributes(BCDFoilVisAtt);
      }// backward cd


    }//cds et!=2

    //barrelfoil
    if(et>1){
      G4Polyhedra* fbarrel_foil = NULL;
      G4Box* fbarrel_foil_tmp = NULL;
      G4Polyhedra* bbarrel_foil = NULL;
      Double_t foil_z[2] = {data->settings->ForwardBarrelZ+data->settings->BarrelLength/2.,data->settings->ForwardBarrelZ-data->settings->PCBLength/2.};
      Double_t foil_inner_r[2] = {data->settings->BarrelDistance-data->settings->BDFoilDistance-data->settings->FBDFoilThickness,data->settings->BarrelDistance-data->settings->BDFoilDistance-data->settings->FBDFoilThickness};
      Double_t foil_outer_r[2] = {data->settings->BarrelDistance-data->settings->BDFoilDistance,data->settings->BarrelDistance-data->settings->BDFoilDistance};
      if(data->VerboseLevel > 0){
        cout<<"ForwardBarrelZ " << data->settings->ForwardBarrelZ<<endl;
	cout<<"BarrelDistance " << data->settings->BarrelDistance<<endl;
	cout<<"BDFoilDistance " << data->settings->BDFoilDistance<<endl;
	cout<<"FBDFoilThickness " << data->settings->FBDFoilThickness<<endl;

	cout<<"creating Barrel screening foil with z = "<<foil_z[0]/mm<<" - "<<foil_z[1]/mm<<" mm, r_i = "<<foil_inner_r[0]/mm<<" - "<<foil_inner_r[1]/mm<<" mm, r_o = "<<foil_outer_r[0]/mm<<" - "<<foil_outer_r[1]/mm<<" mm"<<endl;
      }
      if(data->Cut&(1<<2)){
	//fbarrel_foil_tmp = new G4Box("barrel_screening_tmp",data->settings->BarrelWidth/2.,data->settings->BarrelWidth/2.,data->settings->BarrelLength);
	fbarrel_foil = new G4Polyhedra("barrel_screening",45.*degree,1.5*M_PI,3,2,foil_z,foil_inner_r,foil_outer_r);
	//fbarrel_foil = 
	}
      else{
	fbarrel_foil = new G4Polyhedra("barrel_screening",45.*degree,2.*M_PI,4,2,foil_z,foil_inner_r,foil_outer_r);
      }
      
      G4LogicalVolume* fbarrel_foil_log;
      if(data->ScreeningMaterialName.contains("aluminum")){
	fbarrel_foil_log = new G4LogicalVolume(fbarrel_foil, Aluminum, "barrel_foil_log");
      }
      else if(data->ScreeningMaterialName.contains("mylar")){
	fbarrel_foil_log = new G4LogicalVolume(fbarrel_foil, Mylar, "barrel_foil_log");
      }
      else{
	cerr<<"ERROR in DetectorConstruction: ScreeningMaterialName "<<data->ScreeningMaterialName<<" is unknown!"<<endl;
	exit(1);
      }
      
      new G4PVPlacement(0, G4ThreeVector(0,0,0), "BarrelScreening", fbarrel_foil_log, mother, false, 0);
      
      fbarrel_foil_log->SetVisAttributes(fBDFoilVisAtt);


      if(data->BackwardFoil == 1){
	Double_t foil_b_z[2] = {data->settings->BackwardBarrelZ+data->settings->PCBLength/2.,data->settings->BackwardBarrelZ-data->settings->BarrelLength/2.};
	Double_t foil_inner_r[2] = {data->settings->BarrelDistance-data->settings->BDFoilDistance-data->settings->BBDFoilThickness,data->settings->BarrelDistance-data->settings->BDFoilDistance-data->settings->BBDFoilThickness};
	Double_t foil_outer_r[2] = {data->settings->BarrelDistance-data->settings->BDFoilDistance,data->settings->BarrelDistance-data->settings->BDFoilDistance};

	if(data->VerboseLevel > 3){
	  cout<<"creating Barrel screening foil for backward with z = "<<foil_b_z[0]/mm<<" - "<<foil_b_z[1]/mm<<" mm, r_i = "<<foil_inner_r[0]/mm<<" - "<<foil_inner_r[1]/mm<<" mm, r_o = "<<foil_outer_r[0]/mm<<" - "<<foil_outer_r[1]/mm<<" mm"<<endl;
	}

	if(data->Cut&(1<<2)){
	  bbarrel_foil = new G4Polyhedra("barrel_screening",45.*degree,1.5*M_PI,3,2,foil_b_z,foil_inner_r,foil_outer_r);
	}
	else{
	  bbarrel_foil = new G4Polyhedra("barrel_screening",45.*degree,2.*M_PI,4,2,foil_b_z,foil_inner_r,foil_outer_r);
	}
      
	G4LogicalVolume* bbarrel_foil_log;
	if(data->ScreeningMaterialName.contains("aluminum")){
	  bbarrel_foil_log = new G4LogicalVolume(bbarrel_foil, Aluminum, "bbarrel_foil_log");
	}
	else if(data->ScreeningMaterialName.contains("mylar")){
	  bbarrel_foil_log = new G4LogicalVolume(bbarrel_foil, Mylar, "bbarrel_foil_log");
	}
	else{
	  cerr<<"ERROR in DetectorConstruction: ScreeningMaterialName "<<data->ScreeningMaterialName<<" is unknown!"<<endl;
	  exit(1);
	}

	new G4PVPlacement(0, G4ThreeVector(0,0,0), "BBarrelScreening", bbarrel_foil_log, mother, false, 0);
	
	bbarrel_foil_log->SetVisAttributes(bBDFoilVisAtt);

      }
      else if(data->BackwardFoil > 1){
	if(data->VerboseLevel > 3){
	  cout<<"creating vertical Barrel screening foil with x = "<<data->settings->BBDVertFoilSize/2./mm<<" mm, y = "<<data->settings->BBDVertFoilSize/2./mm<<" mm, thickness = "<<data->settings->BBDFoilThickness/micrometer<<" um"<<endl;
	}
	G4SubtractionSolid* bvert_foil;
	G4Box* bvert_foil_b = new G4Box("bvert_foil_b", data->settings->BBDVertFoilSize/4., data->settings->BBDVertFoilSize/2., data->settings->BBDFoilThickness/2.*10);
	G4Box* bvert_foil_a = new G4Box("bvert_foil_a", data->settings->BBDVertFoilSize/2., data->settings->BBDVertFoilSize/2., data->settings->BBDFoilThickness/2.);
	G4Tubs* bvert_hole = new G4Tubs("bvert_hole",0,data->settings->BBDFoilHole,data->settings->BBDFoilThickness/2.*10,0.,2*M_PI);
	bvert_foil = new G4SubtractionSolid("bvert_foil",bvert_foil_a,bvert_hole);

	if(data->Cut&(1<<2)){
	  bvert_foil = new G4SubtractionSolid("bvert_foil",bvert_foil,bvert_foil_b, new G4RotationMatrix(), G4ThreeVector(data->settings->BBDVertFoilSize/4.,0,0));
	}


	G4LogicalVolume* bvert_foil_log;
	if(data->ScreeningMaterialName.contains("aluminum")){
	  bvert_foil_log = new G4LogicalVolume(bvert_foil, Aluminum, "bvert_foil_log");
	}
	else if(data->ScreeningMaterialName.contains("mylar")){
	  bvert_foil_log = new G4LogicalVolume(bvert_foil, Mylar, "bvert_foil_log");
	}
	else{
	  cerr<<"ERROR in DetectorConstruction: ScreeningMaterialName "<<data->ScreeningMaterialName<<" is unknown!"<<endl;
	  exit(1);
	}

	Double_t foil_b_z = data->settings->BBDVertFoilDistance;
	if(data->VerboseLevel > 3){
	  cout<<"creating vertical Barrel screening foil for backward with z = "<<foil_b_z/mm<<" mm"<<endl;
	}
	new G4PVPlacement(0, G4ThreeVector(0,0,foil_b_z), "BVertScreening", bvert_foil_log, mother, false, 0);
	bvert_foil_log->SetVisAttributes(BVertFoilVisAtt);
      }
      
    }//barrel foil
  }//screening
  //delete[] frotation;
  //delete[] brotation;
  //delete[] ferotation;
  //delete[] berotation;
  //delete[] fpcbrotation;
  //delete[] bpcbrotation;
  //delete[] fepcbrotation;
  //delete[] bepcbrotation;
  //delete[] PCBQuadrant_solid;
  //delete H;
  //delete B;
  //delete C;
  //delete O;
  //delete Mg;
  //delete Al;
  //delete Si;
  //delete Ca;
  //delete Cu;
  //delete Silicon;
  //delete SiO2;
  //delete B2O3;
  //delete CaO;
  //delete Al2O3;
  //delete MgO;
  //delete FiberGlass;
  //delete Epoxy;
  //delete PCB;
  //delete Mylar;

  //delete world;
  //
  //delete fCDVisAtt;
  //delete bCDVisAtt;
  //delete fCDEVisAtt;
  //delete bCDEVisAtt;
  //delete hfCDVisAtt;
  //delete hbCDVisAtt;
  //delete hfCDEVisAtt;
  //delete hbCDEVisAtt;
  //delete fBDVisAtt;
  //delete bBDVisAtt;
  //delete fBDEVisAtt;
  //delete bBDEVisAtt;
  //delete hfBDVisAtt;
  //delete hbBDVisAtt;
  //delete hfBDEVisAtt;
  //delete hbBDEVisAtt;
  //delete fBDPCBVisAtt;
  //delete bBDPCBVisAtt;
  //delete hfBDPCBVisAtt;
  //delete hbBDPCBVisAtt;
  //
  //delete FCDFoilVisAtt;
  //delete BCDFoilVisAtt;
  //delete fBDFoilVisAtt;
  //delete bBDFoilVisAtt;
  //delete BVertFoilVisAtt;
  //delete TargetMaterialVisAtt;
  //delete ChamberVisAtt;

  return(mother);
}




